﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text;
using StoreTransport.Business.Constants;
using StoreTransport.Resources;
using System.Windows.Forms;
using System.Collections;
using System.Reflection;
using StoreTransport.DAO;
using StoreTransport.Data;
using StoreTransport.Business.Services;

namespace StoreTransport.Business.Helper {
    public class CommonHelper {

        public static Dictionary<int, Region> RegionsList = new Dictionary<int, Region>();
        public static Dictionary<int, Area> AreaList = new Dictionary<int, Area>();
        public static Dictionary<int, Product> ProductList = new Dictionary<int, Product>();
        public static Dictionary<int, ProductKind> ProductKindList = new Dictionary<int, ProductKind>();
        public static Dictionary<int, Market> MarketList = new Dictionary<int, Market>();
        public static Dictionary<int, MarketKind> MarketKindList = new Dictionary<int, MarketKind>();
        public static ProductLine CurrentProductLine = null;

        public static void InitCalculateRelatedData(int productlineID){
            if (CurrentProductLine == null || CurrentProductLine.ID != productlineID) {
                StoreTransportDataContext context = GetContext();
                RegionsList = context.Regions.ToDictionary(c => c.ID);
                AreaList = context.Areas.ToDictionary(c => c.ID);
                ProductKindList = context.ProductKinds.Where(c => c.ProductLine == productlineID).ToDictionary(c => c.ID);
                MarketList = context.Markets.ToDictionary(c => c.ID);
                ProductList = context.Products.Where(c =>  c.ProductKind.HasValue && 
                    ProductKindList.Keys.Contains(c.ProductKind.Value)).ToDictionary(c => c.ID);
                MarketKindList = context.MarketKinds.ToDictionary(c => c.ID);
                CurrentProductLine = context.ProductLines.Where(c => c.ID == productlineID).First();
            }
        }

        public static void InitCombobox() {
            CommonConstant.Status.Add(new ComboBoxItem(Status.A.ToString(), StoreTransportResource.Status_Active));
            CommonConstant.Status.Add(new ComboBoxItem(Status.I.ToString(), StoreTransportResource.Status_InActive));

            CommonConstant.StatusDic.Add(Status.A.ToString(), StoreTransportResource.Status_Active);
            CommonConstant.StatusDic.Add(Status.I.ToString(), StoreTransportResource.Status_InActive);

            CommonConstant.MarketType.Add(new ComboBoxItem(MarketType.M.ToString(), StoreTransportResource.MarketType_Market));
            CommonConstant.MarketType.Add(new ComboBoxItem(MarketType.S.ToString(), StoreTransportResource.MarketType_Store));
            CommonConstant.MarketType.Add(new ComboBoxItem(MarketType.P.ToString(), StoreTransportResource.MarketType_Presentation));
            CommonConstant.MarketType.Add(new ComboBoxItem(MarketType.C.ToString(), StoreTransportResource.MarketType_StoreCenter));

            CommonConstant.MarketTypeDic.Add(MarketType.M.ToString(), StoreTransportResource.MarketType_Market);
            CommonConstant.MarketTypeDic.Add(MarketType.S.ToString(), StoreTransportResource.MarketType_Store);
            CommonConstant.MarketTypeDic.Add(MarketType.P.ToString(), StoreTransportResource.MarketType_Presentation);
            CommonConstant.MarketTypeDic.Add(MarketType.C.ToString(), StoreTransportResource.MarketType_StoreCenter);

            CommonConstant.ShipmentDay.Add(new ComboBoxItem("2", StoreTransportResource.TransportDay_Mo));
            CommonConstant.ShipmentDay.Add(new ComboBoxItem("3", StoreTransportResource.TransportDay_Tu));
            CommonConstant.ShipmentDay.Add(new ComboBoxItem("4", StoreTransportResource.TransportDay_We));
            CommonConstant.ShipmentDay.Add(new ComboBoxItem("5", StoreTransportResource.TransportDay_Th));
            CommonConstant.ShipmentDay.Add(new ComboBoxItem("6", StoreTransportResource.TransportDay_Fr));
            CommonConstant.ShipmentDay.Add(new ComboBoxItem("7", StoreTransportResource.TransportDay_Sa));

            CommonConstant.ShipmentDayDic.Add("2", StoreTransportResource.TransportDay_Mo);
            CommonConstant.ShipmentDayDic.Add("3", StoreTransportResource.TransportDay_Tu);
            CommonConstant.ShipmentDayDic.Add("4", StoreTransportResource.TransportDay_We);
            CommonConstant.ShipmentDayDic.Add("5", StoreTransportResource.TransportDay_Th);
            CommonConstant.ShipmentDayDic.Add("6", StoreTransportResource.TransportDay_Fr);
            CommonConstant.ShipmentDayDic.Add("7", StoreTransportResource.TransportDay_Sa);

            CommonConstant.ReportType.Add(ReportType.StoreTS.ToString(), StoreTransportResource.ReportType_StoreTS);
            CommonConstant.ReportType.Add(ReportType.MarketTS.ToString(), StoreTransportResource.ReportType_MarketTS);
            CommonConstant.ReportType.Add(ReportType.StoreMakertTS.ToString(), StoreTransportResource.ReportType_StoreMarketTS);
            CommonConstant.ReportType.Add(ReportType.MarketStoreTS.ToString(), StoreTransportResource.ReportType_MarketStoreTS);
            
        }

        

        public static void SetValueForComboBox(ComboBox box, List<ComboBoxItem> listItem) {
            box.DisplayMember = "Text";
            box.ValueMember = "Value";
            box.DataSource = listItem;
        }

        public static string GetComboBoxItemText(string value, List<ComboBoxItem> listItem) {
            var result = listItem.Where(c => c.Value == value);
            if (result.Count() > 0) {
                return result.First().Value;
            }
            return string.Empty;
        }

        public static void ResetCombobox(ComboBox box) {
            if (box.Items.Count > 0) {
                box.SelectedIndex = 0;
            }
        }

        public static void SetComboboxValue(ComboBox box, object obj) {
            if (obj != null && !string.IsNullOrEmpty(obj.ToString())) {
                box.SelectedValue = obj;
            } else {
                if (box.Items.Count > 0) {
                    box.SelectedIndex = 0;
                }
            }
        }

        public static DataTable FlipDataTable(DataTable my_DataTable) {
            DataTable table = new DataTable();
            for (int i = 0; i <= my_DataTable.Rows.Count; i++) { table.Columns.Add(Convert.ToString(i)); }
            DataRow r;
            for (int k = 0; k < my_DataTable.Columns.Count; k++) {
                r = table.NewRow();
                r[0] = my_DataTable.Columns[k].ToString();
                bool isShow = false;
                for (int j = 1; j <= my_DataTable.Rows.Count; j++) {
                    r[j] = my_DataTable.Rows[j - 1][k];
                    if (r[j] != null && !string.IsNullOrEmpty(r[j].ToString())) {
                        isShow = true;
                    }
                }
                if (isShow) {
                    table.Rows.Add(r);
                }
            }
            return table;
        }

        // code to use string to enum
        //  if(Enum.IsDefined(typeof(DaysOfWeek), "Katillsday"))
        //  StringToEnum<DaysOfWeek>("Katillsday");
        private T StringToEnum<T>(string name) {
            string[] names = Enum.GetNames(typeof(T));
            if (((IList)names).Contains(name)) {
                return (T)Enum.Parse(typeof(T), name);
            } else
                return default(T);
        }

        public static string GetEnumValue(object value, Dictionary<string, string> itemList) {
            if (value != null && itemList.ContainsKey(value.ToString())) {
                return itemList[value.ToString()];
            }
            return string.Empty;
        }

        public static string CheckNumberValue(string value, string fieldName) {
            int number = 0;
            if (!int.TryParse(value, out number) || number <= 0) {
                return string.Format(StoreTransportResource.ErrorMessage_ValueMustBeNumber,
                    fieldName.Replace(":", string.Empty)) + Environment.NewLine + Environment.NewLine;
            }
            return string.Empty;
        }

        public static string CheckRequiredField(string value, string fieldName) {
            if (string.IsNullOrEmpty(value)) {
                return string.Format(StoreTransportResource.ErrorMessage_FieldRequired,
                    fieldName.Replace(":", string.Empty)) + Environment.NewLine + Environment.NewLine;
            }
            return string.Empty;
        }

        public static string CheckPassWordLength(string value, string fieldName) {
            if (value.Length <= 3) {
                return string.Format(StoreTransportResource.ErrorMessage_PasswordLengthNotMatch,
                    fieldName.Replace(":", string.Empty)) + Environment.NewLine + Environment.NewLine;
            }
            return string.Empty;
        }

        public static string GetStringNumber(int? value) {
            return value == null ? string.Empty : value.ToString();
        }
        public static bool IsValidDataToExport() {
            StoreTransportDataContext context = GetContext();
            var invalidChar = ValidData.I.ToString()[0];
            return context.Products.Where(c => c.ValidData == invalidChar).Count() == 0 &&
                context.Markets.Where(c => c.ValidData == invalidChar).Count() == 0;
        }

        public static StoreTransportDataContext GetContext() {
            string connectionString = ConfigurationManager.
                ConnectionStrings[CommonConstant.ConnectionStringKey].ConnectionString;
            return new StoreTransportDataContext(connectionString);
        }

        public static void OpenForm(Form currentForm, Form openForm) {
            Form mdiForm = currentForm.MdiParent;
            foreach (Form f in mdiForm.MdiChildren) {
                f.Close();
            }
            openForm.MdiParent = mdiForm;
            openForm.Width = mdiForm.Width;
            openForm.Height = mdiForm.Height;
            openForm.Show();
        }

        public static bool IsWarningProductOrder(int productLineId) {
            // TODO QMI need to re-implement 
            return ProductOrderService.ShowOrderProductWarning(productLineId);
        }

        public static void HideTabPage(TabControl tabcontrol, TabPage tp) {
            if (tabcontrol.TabPages.Contains(tp))
                tabcontrol.TabPages.Remove(tp);
        }


        public static void ShowTabPage(TabControl tabcontrol, TabPage tp) {
            ShowTabPage(tabcontrol, tp, tabcontrol.TabPages.Count);
        }


        public static void ShowTabPage(TabControl tabcontrol, TabPage tp, int index) {
            if (tabcontrol.TabPages.Contains(tp))
                return;
            InsertTabPage(tabcontrol, tp, index);
        }


        public static void InsertTabPage(TabControl tabcontrol, TabPage tabpage, int index) {
            if (index < 0 || index > tabcontrol.TabCount)
                throw new ArgumentException("Index out of Range.");
            tabcontrol.TabPages.Add(tabpage);
            if (index < tabcontrol.TabCount - 1)
                do {
                    SwapTabPages(tabcontrol, tabpage, (tabcontrol.TabPages[tabcontrol.TabPages.IndexOf(tabpage) - 1]));
                }
                while (tabcontrol.TabPages.IndexOf(tabpage) != index);
            tabcontrol.SelectedTab = tabpage;
        }


        public static void SwapTabPages(TabControl tabcontrol, TabPage tp1, TabPage tp2) {
            if (tabcontrol.TabPages.Contains(tp1) == false || tabcontrol.TabPages.Contains(tp2) == false) {
                throw new ArgumentException("TabPages must be in the TabControls TabPageCollection.");
            }

            int Index1 = tabcontrol.TabPages.IndexOf(tp1);
            int Index2 = tabcontrol.TabPages.IndexOf(tp2);
            tabcontrol.TabPages[Index1] = tp2;
            tabcontrol.TabPages[Index2] = tp1;

            //Uncomment the following section to overcome bugs in the Compact Framework
            //tabcontrol.SelectedIndex = tabcontrol.SelectedIndex; 
            //string tp1Text, tp2Text;
            //tp1Text = tp1.Text;
            //tp2Text = tp2.Text;
            //tp1.Text=tp2Text;
            //tp2.Text=tp1Text;

        }

        public static DataTable RemoveEmptyData(DataTable table, int columnsStartIndex) {
            DataTable returnTable = table.Copy();
            //returnTable.Rows = table
            List<DataRow> removedRows = new List<DataRow>();
            foreach (DataRow row in returnTable.Rows) {
                bool remove = true;
                for (int i = columnsStartIndex; i < returnTable.Columns.Count; i++) {
                    if (row[i] != null && !string.IsNullOrEmpty(row[i].ToString())) {
                        remove = false;
                        break;
                    }
                }
                if (remove) {
                    removedRows.Add(row);
                }
            }
            foreach(DataRow row in removedRows){
                returnTable.Rows.Remove(row);
            }
            return returnTable;
        }

        public static int RoundedByPackage(int quatity, int package) {
            return Convert.ToInt32((quatity / package) + 0.5) * package;
        }

        public static int roundedDown(double number) {
            return Convert.ToInt32(number - 0.5);
        }
    }
    public static class ExtensionMethods {
        public static void DoubleBuffered(this DataGridView dgv, bool setting) {
            Type dgvType = dgv.GetType();
            PropertyInfo pi = dgvType.GetProperty("DoubleBuffered",
                BindingFlags.Instance | BindingFlags.NonPublic);
            pi.SetValue(dgv, setting, null);
        }
    }
}
